﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Data;
using Utility;
using Model;

namespace Service.Codes
{
    /// <summary>
    /// 将winprop生成小文件合并为指纹库格式的文件。
    /// </summary>
    public class WinProp_CombineFile
    {
        private NLog.Logger logger = new NLog.LogFactory().GetCurrentClassLogger();

        /// <summary>
        /// 1、判断小区类型，过滤室内小区
        /// 2、根据工参里最大最小经纬度，划定范围
        /// 3、根据1000米划分片
        /// 4、确定每个分片经纬度范围
        /// 5、根据分片范围外扩500米，查询小区
        /// 6、加载分片范围内小区数据到一个集合
        /// 7、过滤范围外的栅格
        /// 8、过滤高层室外栅格
        /// 9、根据栅格ID分组
        /// 10、按RSRP排序，取前11条
        /// 11、最大值为主服务小区
        /// 12、过滤主服务小区小于-120的分组
        /// 13、写文件
        /// </summary>
        /// <param name="sliceLength"></param>
        /// <param name="maxDegreeOfParallelism">并行子进程数</param>
        /// <param name="fileInfoCount"></param>
        /// <param name="item">调用是参数传递类，包含参数：｛city,cellpath,winpropoutput,fpdpath｝</param>
        public void Execute(int sliceLength, int maxDegreeOfParallelism, int fileInfoCount, SyntheticPar item)
        {
            logger.Info("开始合成");

            string city = item.City;
            string cellPath = item.CellPath;
            string resultFolder = item.ResultFolder;
            string fpdPath = Path.Combine(resultFolder, "combine");

            if (!Directory.Exists(fpdPath)) {
                Directory.CreateDirectory(fpdPath);
            }

            string pamr = sliceLength + "&" + fileInfoCount + "&" + city + "&" + cellPath + "&" + resultFolder + "&" + item.GridLength + "&";

            DataTable tabCell = ExcelUtil.ExcelToDataTable(cellPath, "站点信息", true);

            #region 1、判断小区类型，过滤室内小区

            List<Res_Cell> allCellNew = new List<Res_Cell>();

            foreach (DataRow dr in tabCell.Rows)
            {
                
                Res_Cell cell = new Res_Cell();

                double mx = 0, my = 0;

                cell.CellName = dr["小区名称"].ToString().Replace('\\','_');
                cell.HorizonAngleToEast = (int)Convert.ToDouble(dr["扇区方位角"]);
                cell.Longitude = Convert.ToDouble(dr["小区经度"]);
                cell.Latitude = Convert.ToDouble(dr["小区纬度"]);
                cell.ObjectID = Convert.ToInt32(dr["ObjectId"]);

                MecatorUtil.loc_to_mercator(cell.Longitude, cell.Latitude, ref mx, ref my);

                cell.CellLongitude = mx;
                cell.CellLatitude = my;

                allCellNew.Add(cell);
                
            }

            tabCell.Dispose();
            tabCell = null;

            string indoorGridFile = System.AppDomain.CurrentDomain.BaseDirectory + "\\" + city + ".txt";

            #endregion

            #region 2、根据工参里最大最小经纬度，划定范围
            double maxX = Math.Ceiling(allCellNew.Max(o => o.CellLongitude));
            double maxY = Math.Ceiling(allCellNew.Max(o => o.CellLatitude));
            double minX = Math.Floor(allCellNew.Min(o => o.CellLongitude));
            double minY = Math.Floor(allCellNew.Min(o => o.CellLatitude));
            #endregion

            #region 3、根据1000米划分片 4、确定每个分片经纬度范围 5、根据分片范围外扩500米，查询小区

            List<string> keys = new List<string>();
            for (double i = minX; i < maxX + sliceLength; i = i + sliceLength)
            {
                for (double j = minY; j < maxY + sliceLength; j = j + sliceLength)
                {
                    List<Res_Cell> lsCell = allCellNew.Where(o => o.CellLongitude >= i - 500 && o.CellLongitude <= i + sliceLength + 500 && o.CellLatitude >= j - 500 && o.CellLatitude <= j + sliceLength + 500).ToList();
                    if (lsCell.Count > 0)
                    {
                        keys.Add(pamr + i + "_" + j);
                    }
                }
            }

            allCellNew.Clear();
            allCellNew = null;
            #endregion

            foreach(string key in keys)
            {
                logger.Info(key);

                // Process process = Process.Start(System.AppDomain.CurrentDomain.BaseDirectory + "\\Sub.MultiProcessCombine.exe", key);
                // process.WaitForExit();

                using (System.Diagnostics.Process myProcess = new System.Diagnostics.Process())
                {
                    myProcess.StartInfo = new System.Diagnostics.ProcessStartInfo(System.AppDomain.CurrentDomain.BaseDirectory + "\\Sub.MultiProcessCombine.exe", key);
                    myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    myProcess.Start();
                    myProcess.WaitForExit();
                }
            }

            logger.Info("结束合成");
        }

    }
}
